//
//  KDWeekView.m
//  KDCalendarControl
//
//  Created by Keith Duncan on 28/06/2007.
//  Copyright 2007 thirty-three. All rights reserved.
//

#import "AFWeekControl.h"

#import "AFWeekCell.h"

#define MAX_WEEKDAYS 7

@interface AFWeekControl()
@property (retain) NSEvent *initialEvent;
@end

@implementation AFWeekControl

@dynamic cell;
@synthesize datasource;
@synthesize initialEvent;

+ (Class)cellClass {
	return [AFWeekCell class];
}

- (void)dealloc {
	[initialEvent release];
	
	[super dealloc];
}

- (void)awakeFromNib {
	[self reloadData];
}

- (void)viewWillMoveToSuperview:(NSView *)view {
	[super viewWillMoveToSuperview:view];
	
	[[NSNotificationCenter defaultCenter] removeObserver:self];
	
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(display) name:NSWindowDidResignKeyNotification object:[view window]];
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(display) name:NSWindowDidBecomeKeyNotification object:[view window]];
}

- (void)resetCursorRects {
	[self addCursorRect:[[self cell] drawingRectForBounds:[self bounds]] cursor:[NSCursor pointingHandCursor]];
}

- (void)reloadData {
	NSMutableIndexSet *newSelectedDays = [NSMutableIndexSet indexSet];
	
	for (NSUInteger currentIndex = 0; currentIndex < MAX_WEEKDAYS; currentIndex++) {
		AFWeekday weekday = (currentIndex+1);
		if (![datasource weekview:self isEnabledForDay:weekday]) continue;
		
		[newSelectedDays addIndex:weekday];
	}
	
	[[self cell] setSelectedDays:newSelectedDays];
	[self setNeedsDisplay:YES];
}

- (void)drawRect:(NSRect)frame {
	[[self cell] drawWithFrame:[self bounds] inView:self];
}

// Note: point will be converted to internal coordinate system
- (AFWeekday)_weekdayForEventPoint:(NSPoint)point {
	point = [self convertPoint:point fromView:nil];
	
	NSRect contentRect = [[self cell] drawingRectForBounds:[self bounds]];
	
	AFWeekday weekday = 0;
	for (NSUInteger currentIndex = 0; currentIndex < MAX_WEEKDAYS; currentIndex++) {
		NSRect currentDayRect = AFDayRectForRowRect(contentRect, currentIndex, MAX_WEEKDAYS);
		if (!NSMouseInRect(point, currentDayRect, [self isFlipped])) continue;
		
		weekday = (currentIndex+1);
		break;
	}
	
	return weekday;
}

- (void)mouseDown:(NSEvent *)event {
	_dragged = NO;
	self.initialEvent = event;
	
	_initialDragState = [[self.cell selectedDays] containsIndex:[self _weekdayForEventPoint:[self.initialEvent locationInWindow]]];
}

- (void)mouseDragged:(NSEvent *)event {
	_dragged = YES;
	
	NSPoint hitPoints[2] = {[self.initialEvent locationInWindow], [event locationInWindow]};
	AFWeekday hitDays[2] = {[self _weekdayForEventPoint:hitPoints[0]], [self _weekdayForEventPoint:hitPoints[1]]};
	if (hitDays[0] == hitDays[1]) return;
	
	[[self datasource] weekview:self setEnabled:_initialDragState forDay:hitDays[1]];
	[self reloadData];
}

- (void)mouseUp:(NSEvent *)event {
	if (!_dragged) {
		NSPoint hitPoints[2] = {[self.initialEvent locationInWindow], [event locationInWindow]};
		AFWeekday hitDays[2] = {[self _weekdayForEventPoint:hitPoints[0]], [self _weekdayForEventPoint:hitPoints[1]]};
		
		if ((hitDays[0] != 0 && hitDays[1] != 0) && !(hitDays[0] != hitDays[1])) {
			// Note: getting to this point means the selectedDay is valid
			[self.datasource weekview:self setEnabled:![[[self cell] selectedDays] containsIndex:hitDays[1]] forDay:hitDays[1]];
			[self reloadData];
		}
	}

	self.initialEvent = nil;
}

@end

#undef MAX_WEEKDAYS
